class DivElement extends Element {
  constructor(layoutNode, context) {
    super(layoutNode, context)
  }

  drawBg() {
    let { react, style } = this.layoutNode

    this.ctx.drawImage(this.layoutNode.ele, react.left, react.top, react.width, react.height)
  }

  parseLinearGradient(cssColorImg) {
    let { react, style } = this.layoutNode
    let colorList = []
    /* 
     需要注意渐变色不是从当前矩形开始，
     而是canvas坐标系为参考，
     否则矩形不是位于左上角渐变色绘制会失败
    */
    /* 默认值为 to bottom */
    let linearDirection = {
      x1: react.left,
      y1: react.top,
      x2: react.left,
      y2: react.top + react.height,
    }

    cssColorImg = cssColorImg.slice(16, -1).trim()

    if (!cssColorImg.startsWith('rgb')) {
      // 不是rgb开头可能是 to left , 90deg形式
      // 设置了渐变方向需要解析渐变方向
      let splitColor = cssColorImg.split(',')

      let parseDirection = splitColor.shift() //第一项为方向，其他项为颜色值
      cssColorImg = splitColor.join(',')

      {
        // input  rgb(230, 100, 101), rgb(145, 152, 229), rgb(0, 128, 0)

        colorList = cssColorImg.split('),') // color arr

        for (let c = 0; c < colorList.length; c++) {
          const color = colorList[c]
          if (c !== colorList.length - 1) {
            colorList[c] = color + ')'
          }
        }
      }

      if (parseDirection.endsWith('deg')) {
        let deg = parseFloat(parseDirection)
        // TODO.....
        linearDirection = {
          x1: react.left + react.width,
          y1: react.top,
          x2: react.left,
          y2: react.top,
        }
      } else {
        switch (parseDirection) {
          case 'to left':
            linearDirection = {
              x1: react.left + react.width,
              y1: react.top,
              x2: react.left,
              y2: react.top,
            }
            break
          case 'to top':
            linearDirection = {
              x1: react.left,
              y1: react.top + react.height,
              x2: react.left,
              y2: react.top,
            }
            break
          case 'to right':
            linearDirection = {
              x1: react.left,
              y1: react.top,
              x2: react.left + react.width,
              y2: react.top + react.height,
            }
            break
          case 'to bottom':
            linearDirection = {
              x1: react.left,
              y1: react.top,
              x2: react.left,
              y2: react.top + react.height,
            }
            break
          case 'to left top':
            // linearDirection = { x1: 0, y1: 0, x2: 170, y2: 0 } todo.....
            break
          case 'to right top':
            // linearDirection = { x1: 0, y1: 0, x2: 170, y2: 0 } todo.....
            break
          case 'to right bottom':
            // linearDirection = { x1: 0, y1: 0, x2: 170, y2: 0 } todo.....
            break
          case 'to left bottom':
            // linearDirection = { x1: 0, y1: 0, x2: 170, y2: 0 } todo.....
            break
        }
      }
    } else {
      colorList = cssColorImg.split('),') // color arr
      colorList[0] += ')'
    }

    let linearGradient = this.ctx.createLinearGradient(
      linearDirection.x1,
      linearDirection.y1,
      linearDirection.x2,
      linearDirection.y2
    )

    let colorLength = colorList.length
    /* 递推颜色百分比规律
    2 0 1  0/1=0
    3 0 0.5   1/ 2 = 0.5
    4 0 0.33 0.66 1 1/3 = 0.33
    5 0 0.25 0.5 0.75 1   1/4 =  0.25
    6 0 0.16 0.32 0.48 0.54 
    */

    for (let c = 0; c < colorList.length; c++) {
      const color = colorList[c].trim()
      if (colorLength < 2) {
        linearGradient.addColorStop(c, color)
      } else {
        let temp = 1 / (colorLength - 1)
        linearGradient.addColorStop(temp * c, color)
      }
    }

    this.ctx.fillStyle = linearGradient
  }

  parseShadow(style) {
    //DEMO  style.boxShadow = rgb(136, 136, 136) 10px 10px 5px 0px
    let parseBoxShadow = style.boxShadow.split(')')
    let shadowColor = parseBoxShadow[0] + ')'
    let shadowOffset = parseBoxShadow[1].split(' ')
    shadowOffset.shift()
    let shadowOffsetX = shadowOffset[0]
    let shadowOffsetY = shadowOffset[1]
    let shadowBlur = shadowOffset[2]

    this.ctx.shadowBlur = parseFloat(shadowBlur)
    this.ctx.shadowOffsetX = parseFloat(shadowOffsetX)
    this.ctx.shadowOffsetY = parseFloat(shadowOffsetY)
    this.ctx.shadowColor = shadowColor
  }
  parseRadialGradient() {
    /// todo ..........
    // const radialGradient = this.ctx.createRadialGradient(75, 50, 5, 90, 60, 100)
    // radialGradient.addColorStop(0, 'red')
    // radialGradient.addColorStop(1, 'white')
    // this.ctx.fillStyle = radialGradient
  }

  parseBackgroundImage(style) {
    let bgSrc = style.backgroundImage.slice(5, -2)
    this.layoutNode.src = bgSrc
    this.layoutNode.ele = new Image()
    this.layoutNode.ele.src = bgSrc
    this.layoutNode.ele.onload = () => {
      this.drawBg()
    }
  }

  draw() {
    let { react, style } = this.layoutNode
    if (this.layoutNode.ignore) {
      return
    }
    this.ctx.fillStyle = style.backgroundColor

    let backImage = style.backgroundImage !== 'none' && style.backgroundImage
    if (backImage) {
      if (backImage.startsWith('url')) {
        this.parseBackgroundImage(style)
        return
      } else if (backImage.startsWith('linear-gradient')) {
        this.parseLinearGradient(backImage)
      } else if (backImage.startsWith('radial-gradient')) {
        this.parseRadialGradient(backImage)
        // 径向渐变实现
      }
    }

    this.parseNodeMatrix()

    let hasBgColor = !(style.backgroundColor === 'rgba(0, 0, 0, 0)')
    //   //透明度为0会造成阴影显示不出，设为白色,
    let stroke = false,
      fill = false
    if (style.boxShadow && style.boxShadow !== 'none') {
      fill = true
      this.parseShadow(style)
      if (!hasBgColor) {
        this.ctx.fillStyle = 'rgb(255,255,255)'
      }
    }
    let borderWidth = style.borderWidth && parseFloat(style.borderWidth)
    let radius = parseInt(style.borderRadius)
    if (borderWidth) {
      this.ctx.lineWidth = style.borderWidth
      if (hasBgColor) {
        this.ctx.fillStyle = style.backgroundColor
        this.ctx.strokeStyle = style.borderColor
        stroke = true
        fill = true
      } else {
        this.ctx.strokeStyle = style.borderColor
        stroke = true
      }
    } else {
      fill = true
    }

    this.roundedRect(
      react.left,
      react.top,
      react.width,
      react.height,
      radius,
      style.strokeStyle,
      style.borderStyle,
      stroke,
      fill
    )
    this.ctx.lineWidth = 1

    this.clearShadow()
  }
  clearShadow() {
    //绘制完清理阴影否则会影响后边矩形绘制
    this.ctx.shadowBlur = 0
    this.ctx.shadowOffsetX = 0
    this.ctx.shadowOffsetY = 0
    this.ctx.shadowColor = '#000'
  }
}
